package edu.arizona.bio5.onto.decomposition.locality;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.semanticweb.owlapi.model.OWLDataRange;
import org.semanticweb.owlapi.model.OWLDatatype;
import org.semanticweb.owlapi.model.OWLEntity;

import uk.ac.manchester.cs.util.SetUtils;

/**
 * A collection of utility methods for testing locality
 * 
 * 
 * @author Pavel Klinov
 *
 */
public class LocalityUtils {

	protected static final Set<OWLEntity> EMPTY_SIG = Collections.emptySet();
	
    /**
     * (c) Mike Smith, Clark & Parsia, LLC
     * www.clarkparsia.com
     * 
     * This is a convenience method for determining whether a given data range expression is the top datatype
     * or a built-in datatype. This is used in the bottom- and top-equivalence evaluators
     * for treating cardinality restrictions.
     * @param dataRange a data range expression
     * @return <code>true</code> if the specified data range expression is the top datatype
     *         or a built-in datatype; <code>false</code> otherwise
     */
    protected static boolean isTopOrBuiltInDatatype(OWLDataRange dataRange) {
        if (dataRange.isDatatype()) {
            OWLDatatype dataType = dataRange.asOWLDatatype();
            return (dataType.isTopDatatype() || dataType.isBuiltIn());
        }
        else
            return false;
    }

    /**
     * (c) Mike Smith, Clark & Parsia, LLC
     * www.clarkparsia.com 
     * 
     * This is a convenience method for determining whether a given data range expression is the top datatype
     * or a built-in infinite datatype. This is used in the bottom- and top-equivalence evaluators
     * for treating cardinality restrictions.
     * @param dataRange a data range expression
     * @return <code>true</code> if the specified data range expression is the top datatype
     *         or a built-in infinite datatype; <code>false</code> otherwise
     */
    protected static boolean isTopOrBuiltInInfiniteDatatype(OWLDataRange dataRange) {
        if (dataRange.isDatatype()) {
            OWLDatatype dataType = dataRange.asOWLDatatype();
            return (dataType.isTopDatatype() || (dataType.isBuiltIn() && !dataType.getBuiltInDatatype().isFinite()));
        }
        else
            return false;
    }

    protected static Set<OWLEntity> getSingletonSignature(OWLEntity name) {
    	
    	return Collections.singleton(name);
    }
	
	protected static void saveName(OWLEntity name, Collection<? extends OWLEntity> sig, Collection<Set<OWLEntity>> subSigs) {
		
		if (sig.contains(name)) subSigs.add(Collections.singleton(name)); 
	}
	
	protected static void saveEmptySignature(Collection<Set<OWLEntity>> subSigs) {
		//Reset the signatures, the empty set is always the minimal w.r.t. inclusion
		subSigs.clear();
		subSigs.add(EMPTY_SIG);
	}
	
	/*
	 * Saves all pairs for the given set of names (order is unimportant)
	 */
	protected static void saveAllPairs(List<OWLEntity> names, Collection<Set<OWLEntity>> subSigs) {

		for (int i = 0; i < names.size() - 1; i++) {
			
			for (int j = i + 1; j < names.size(); j++) {
				
				SetUtils.addAndMinimizeWrtInclusion(new HashSet<OWLEntity>(Arrays.asList(names.get(i), names.get(j))), subSigs);
			}
		}
	}	
}
